package com.fulihui.wgj.exception;


import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.extension.Activate;
import com.alibaba.dubbo.rpc.Filter;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.Result;
import com.alibaba.dubbo.rpc.RpcException;
import com.alibaba.dubbo.rpc.RpcResult;
import com.fulihui.common.builder.rpc.RpcResultBuilder;
import com.fulihui.common.error.InvokeServiceException;
import com.fulihui.common.result.rpc.BaseResult;
import com.fulihui.common.result.rpc.PageResult;
import com.fulihui.common.result.rpc.SimpleResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;

/**
 * dubbo服务器错误过滤器
 *
 * @author: Levon
 * @date: 2018-08-09 16:31
 */
@Activate(group = Constants.PROVIDER)
public class ExceptionFilter implements Filter {

    private final transient Logger LOG = LoggerFactory.getLogger(getClass());

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        Class<?> clz = invoker.getInterface();
        Method method;
        try {
            method = clz.getMethod(invocation.getMethodName(), invocation.getParameterTypes());
        } catch (NoSuchMethodException e) {
            throw new RpcException(e);
        }
        Result result = invoker.invoke(invocation);
        if (result.hasException()) {
            if (result.getException() instanceof InvokeServiceException) {
                InvokeServiceException invokeServiceException = (InvokeServiceException) result
                        .getException();
                RpcResult rpcResult = new RpcResult();
                Class<?> returnType = method.getReturnType();
                if (returnType.equals(BaseResult.class)) {
                    rpcResult.setValue(RpcResultBuilder.fail((Class<BaseResult>) returnType,
                            invokeServiceException.getErrcode(), invokeServiceException.getErrmsg()));
                } else if (returnType.equals(SimpleResult.class)) {
                    rpcResult.setValue(RpcResultBuilder.failSimple((Class<SimpleResult>) returnType,
                            invokeServiceException.getErrcode(), invokeServiceException.getErrmsg()));
                } else if (returnType.equals(PageResult.class)) {
                    rpcResult.setValue(RpcResultBuilder.fail((Class<PageResult>) returnType,
                            invokeServiceException.getErrcode(), invokeServiceException.getErrmsg()));
                } else {
                    rpcResult.setValue(RpcResultBuilder.fail(invokeServiceException.getErrcode(), invokeServiceException.getErrmsg()));
                }
                return rpcResult;
            }
        }
        return result;
    }
}
